﻿using AutoMapper;
using Furion.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using XinGuanERP.Db;
using XinGuanERP.Models.Po.business;
using XinGuanERP.Models.Vo.business;
using XinGuanERP.Services.business.IServices;
using XinGuanERP.Utils;

namespace XinGuanERP.Services.business
{
    public class ProductCategoryService : IProductCategoryService, ITransient
    {
        private readonly DefaultDbContext _defaultDbContext;
        public ProductCategoryService(DefaultDbContext defaultDbContext)
        {
            _defaultDbContext = defaultDbContext;
        }

        public bool AddProductCategory(ProductCategoryVo productCategoryVo)
        {
            var config = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<ProductCategoryVo, ProductCategory>()
                    .BeforeMap((src, des) => src.Id = StrUtil.GUID())
                    .AfterMap((src, des) => des.CreateTime = DateTime.Now)
                    .BeforeMap((src, des) => des.CreateUserId = SecurityUtil.FindClaimValue("UserId"))
                    .BeforeMap((src, des) => des.CreateUserName = SecurityUtil.FindClaimValue("UserName"));
            });
            var mapper = config.CreateMapper();
            _defaultDbContext.ProductCategories.Add(mapper.Map<ProductCategory>(productCategoryVo));
            return _defaultDbContext.SaveChanges() > 0;
        }

        public bool UpdateProductCategory(ProductCategoryVo productCategoryVo)
        {
            var res = _defaultDbContext.ProductCategories.FirstOrDefault(t => t.Id == productCategoryVo.Id);
            if (res == null) return false;
            var config = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<ProductCategoryVo, ProductCategory>()
                    .AfterMap((src, des) => des.UpdateTime = DateTime.Now)
                    .BeforeMap((src, des) => des.UpdateUserId = SecurityUtil.FindClaimValue("UserId"))
                    .BeforeMap((src, des) => des.UpdateUserName = SecurityUtil.FindClaimValue("UserName"));
            });
            var mapper = config.CreateMapper();
            mapper.Map(productCategoryVo, res);
            _defaultDbContext.ProductCategories.Update(res);
            return _defaultDbContext.SaveChanges() > 0;
        }

        public bool DeleteProductCategory(string id)
        {
            var res = _defaultDbContext.ProductCategories.FirstOrDefault(t => t.Id == id);
            if (res == null) return false;
            _defaultDbContext.ProductCategories.Remove(res);
            return _defaultDbContext.SaveChanges() > 0;
        }

        public PageResult<ProductCategoryVo> GetProductCategoryWithPage(int page, int pageSize, ProductCategoryVo productCategoryVo)
        {
            var res = new List<ProductCategory>();
            var count = 0;
            var sql = _defaultDbContext.ProductCategories.OrderBy(t => t.Sort).AsQueryable();
            res = sql.Skip((page - 1) * pageSize).Take(pageSize).ToList();
            count = sql.Count();
            if (!string.IsNullOrWhiteSpace(productCategoryVo.Name))
            {
                res = sql.Where(t => 
                        EF.Functions.Like(t.Name, "%" + productCategoryVo.Name + "%"))
                    .Skip((page - 1) * pageSize).Take(pageSize).ToList();
                count = sql.Where(t =>
                    EF.Functions.Like(t.Name, "%" + productCategoryVo.Name + "%")).Count();
            }
            var config = new MapperConfiguration(cfg => cfg.CreateMap<ProductCategory, ProductCategoryVo>());
            var mapper = config.CreateMapper();
            return new PageResult<ProductCategoryVo>()
            {
                Items = res.Select(item => mapper.Map<ProductCategoryVo>(item)).ToList(),
                Total = count
            };
        }

        public PageResult<ProductCategoryTreeNodeVo> GetProductCategoryTreeWithPage(int page, int pageSize)
        {
            var productCategoryList = _defaultDbContext.ProductCategories.ToList();
            var config = new MapperConfiguration(cfg => cfg.CreateMap<ProductCategory, ProductCategoryVo>());
            var mapper = config.CreateMapper();
            var productCategoryVoList = productCategoryList.Select(item => mapper.Map<ProductCategoryVo>(item)).ToList();
            var nodesVoList = ConvertToTreeNodeVo(productCategoryVoList);
            var tree = BuildProductCategoryTree(nodesVoList);
            tree = tree.Skip((page - 1) * pageSize).Take(pageSize).ToList();
            var count = tree.Count();
            return new PageResult<ProductCategoryTreeNodeVo>()
            {
                Items = tree,
                Total = count
            };
        }

        private static List<ProductCategoryTreeNodeVo> ConvertToTreeNodeVo(
            List<ProductCategoryVo> productCategoryVoList)
        {
            var nodes = new List<ProductCategoryTreeNodeVo>();
            if (productCategoryVoList.Count != 0)
            {
                var config =
                    new MapperConfiguration(cfg => cfg.CreateMap<ProductCategoryVo, ProductCategoryTreeNodeVo>());
                var mapper = config.CreateMapper();
                foreach (var item in productCategoryVoList)
                {
                    var productCategoryTreeNodeVo = new ProductCategoryTreeNodeVo();
                    nodes.Add(mapper.Map(item, productCategoryTreeNodeVo));
                }
            }
            return nodes;
        }

        /// <summary>
        /// 递归获取树形结构
        /// </summary>
        /// <param name="nodes"></param>
        /// <returns></returns>
        private static List<ProductCategoryTreeNodeVo> BuildProductCategoryTree(List<ProductCategoryTreeNodeVo> nodes)
        {
            // 根节点
            var rootMenu = new List<ProductCategoryTreeNodeVo>();
            foreach (var nav in nodes)
            {
                if (nav.PId == null)
                {
                    nav.Lev = 1;
                    rootMenu.Add(nav);
                }
            }

            rootMenu = rootMenu.OrderBy(t => t.Sort).ToList();
            // 为根菜单设置子菜单，getChild是递归调用的
            foreach (var nav in rootMenu)
            {
                nav.Children = GetChild(nav, nodes);
            }
            return rootMenu;
        }

        private static List<ProductCategoryTreeNodeVo> GetChild(ProductCategoryTreeNodeVo pNode, List<ProductCategoryTreeNodeVo> nodes)
        {
            var childList = new List<ProductCategoryTreeNodeVo>();
            foreach (var nav in nodes)
            {
                // 遍历所有节点，将所有菜单的父id与传过来的根节点的id比较
                //相等说明：为该根节点的子节点。
                if (nav.PId == pNode.Id)
                {
                    nav.Lev = pNode.Lev + 1;
                    childList.Add(nav);
                }
            }
            
            // 递归
            foreach (var nav in childList)
            {
                nav.Children = GetChild(nav, nodes);
            }
            childList = childList.OrderBy(t => t.Sort).ToList();//排序
            //如果节点下没有子节点，返回一个空List（递归退出）
            if (childList.Count == 0)
            {
                return null;
            }
            return childList;
        }

        /// <summary>
        /// 获取父级分类（2级树）
        /// </summary>
        /// <returns></returns>
        public List<ProductCategoryTreeNodeVo> GetParentProductCategoryTree()
        {
            var productCategoryList = _defaultDbContext.ProductCategories.ToList();
            var config = new MapperConfiguration(cfg => cfg.CreateMap<ProductCategory, ProductCategoryVo>());
            var mapper = config.CreateMapper();
            var productCategoryVoList = productCategoryList.Select(item => mapper.Map<ProductCategoryVo>(item)).ToList();
            var nodesVoList = ConvertToTreeNodeVo(productCategoryVoList);
            var tree = BuildProductCategoryTree(nodesVoList);
            return tree;
        }

        ///// 获取二级父级分类
        //private static List<ProductCategoryTreeNodeVo> BuildParentProductCategoryTree(List<ProductCategoryTreeNodeVo> nodes)
        //{
        //    //根节点
        //    var rootMenu = new List<ProductCategoryTreeNodeVo>();
        //    foreach (var nav in nodes)
        //    {
        //        if (nav.PId == null)
        //        {
        //            nav.Lev = 1;
        //            rootMenu.Add(nav);
        //        }
        //    }
        //    rootMenu = rootMenu.OrderBy(t => t.Sort).ToList();
        //    //为根菜单设置子菜单，getChild是递归调用的
        //}
    }
}
